package com.zlp.partice.jvm;

/**
 * @author: zhulaiping
 * @create: 2021-12-07 12:05
 *
 * todo:
 *  1. 解析：编译时就能确定方法的调用版本的称为解析，
 *      静态方法、私有方法、实例构造器、父类方法。这些方法称为非虚方法，它们在类加载的时候就会把符号引用解析为该方法的直接引用
 *  2. 静态分派：所有依赖静态类型来定位方法执行版本的分派动作称为静态分派。静态分派的典型应用就是方法重载。
 *      静态分派发生在编译阶段，因此确定静态分派的动作实际上不是由虚拟机来执行的，而是由编译器来完成
 *      如果编译器无法确定要自定转型为哪种类型，会提示类型模糊，拒绝编译。
 *  3.动态分派根据类的虚方法表来确定去调用哪个方法
 *      虚方法表中存放着各个方法的实际入口地址。如果某个方法在子类中没有被重写，那子类的虚方法表里面的地址入口和父类相同方法的地址入口是一致的，
 *      都是指向父类的实际入口。如果子类中重写了这个方法，子类方法表中的地址将会替换为指向子类实际版本的入口地址
 *  4.方法调用的常用概念
 *      1. 静态链接：
 *      2. 动态链接：指向运行时常量池的方法引用
 *      3. 晚绑定：
 *      4. 早绑定： 绑定是字段，方法或类有符号引用变为直接引用的过程
 *      5. 静态分派：所有依赖静态类型来定位方法执行版本的分派动作称为静态分派
 *      6. 动态分派：根据类的虚方法表来确定去调用哪个方法
 *      7. 非虚方法：被invokestatic和invokespecial指令调用的方法，包括静态，私有，实例，父实例，final方法 ，这5种方法在类加载的时候就会将符号引用转化为直接引用
 *      8.
 *
 **/
public class MethodCall {
    static abstract class Human{
    }
    static class Man extends Human{
    }
    static class Woman extends Human{
    }
    public void sayHello(Human guy){
        System.out.println("hello,guy!");
    }
    public void sayHello(Man guy){
        System.out.println("hello,gentlemen!");
    }
    public void sayHello(Woman guy){
        System.out.println("hello,lady!");
    }

    public static void main(String[] args) {
        MethodCall call = new MethodCall();
        //静态类型   -  动态类型
        Human man=new Man();
        Human woman=new Woman(); //实际类型变化,实际类型却是不确定的
        call.sayHello(man);
        call.sayHello(woman);
    }
}
